<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of Plume Framework, a simple PHP Application Framework.
# Copyright (C) 2001-2006 Loic d'Anterroches and contributors.
#
# Plume Framework is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Plume Framework is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# ***** END LICENSE BLOCK ***** */

Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse');
Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404');
Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel');
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');

/**
 * Views of the Admin application.
 */
class Admin_Views
{
    /**
     * Init the admin for all the views.
     */
    function __construct()
    {
        Admin_Admin::start();
    }

    /**
     * List the items of a model.
     */
    public $listItems_precond = array('Pluf_Precondition::staffRequired');

    function listItems($request, $match)
    {
        $model_name = Admin_Admin::getModelName($match[1], $match[2]);
        if (false == $model_name) {
            throw new Pluf_HTTP_Error404();
        }
        $item = Pluf::factory($model_name);
        // Check the rights to list
        if (!$request->user->hasPerm($model_name.'.list')) {
            return new Pluf_HTTP_Response_Forbidden($request);
        }
        // Get the paginator for the model
        $pag = Admin_Admin::getModelDetails($match[1], $match[2], 
                                            'paginator', 'Admin_Paginator');
        $paginator = Pluf::factory($pag, $item);
        $paginator->setFromRequest($request);
        $paginator->item_extra_props = array('_app_name' => $match[1],
                                             '_model_path' => $match[2]);
        $paginator->action = array('Admin_Views::listItems', array($match[1], $match[2]));
        $paginator->edit_action = array('Admin_Views::editItem',
                                        '_app_name', '_model_path', 'id');
        $list_display = Admin_Admin::getModelDetails($match[1], $match[2], 
                                                     'list_display', array());
        $paginator->configure($list_display);
        if (isset($item->_a['verbose'])) {
            $name = Admin_Views_ucfirst($item->_a['verbose']);
        } else {
            $name = Admin_Views_ucfirst(str_replace('_', ' ', $item->_a['model']));
        }
        $page_title = sprintf(__('Select %s to change'), $name);
        return Pluf_Shortcuts_RenderToResponse('admin/list-items.html',
                                               array('page_title' => $page_title,
                                                     'app_path' => $match[1], 
                                                     'model_path' => $match[2],
                                                     'model_name' => $name,
                                                     'items'=>$paginator,
                                                     'user' => $request->user),
                                               $request);

    }

    /**
     * View the list of applications and models.
     */
    public $index_precond = array('Pluf_Precondition::staffRequired');

    function index($request, $match)
    {
        $apps = Admin_Admin::getInstalledApp();
        $app_list = new Pluf_Template_ContextVars();
        foreach ($apps as $app) {
            $app_list[$app['name']] = new Pluf_Template_ContextVars(array('name' => $app['name'],
                                                            'path' => $app['path'],
                                                            'models' => new Pluf_Template_ContextVars(),
                                                            )
                                                      ); 
            foreach ($app['models'] as $path=>$model_details) {
                $model = Pluf::factory($model_details['model']);
                if (isset($model->_a['verbose'])) {
                    $model_name = Admin_Views_ucfirst($model->_a['verbose']);
                } else {
                    $model_name = Admin_Views_ucfirst(str_replace('_', ' ', $model_details['model']));
                }
                $_t = new Pluf_Template_ContextVars(array('name'=>$model_name, 
                                                          'path'=>$path));
                $app_list[$app['name']]['models'][] = $_t;
            }

        }
        $context = array('page_title' => __('Administration'),
                         'app_list' => $app_list);
        return Pluf_Shortcuts_RenderToResponse('admin/index.html', $context,
                                               $request);
    }

    /**
     * List the items of a model.
     */
    public $editItem_precond = array('Pluf_Precondition::staffRequired');

    function editItem($request, $match)
    {
        $model_name = Admin_Admin::getModelName($match[1], $match[2]);
        if (false == $model_name) {
            throw new Pluf_HTTP_Error404();
        }
        // Check the rights to edit
        if (!$request->user->hasPerm($model_name.'.update')) {
            return new Pluf_HTTP_Response_Forbidden($request);
        }
        $item = Pluf_Shortcuts_GetObjectOr404($model_name, $match[3]);
        if (isset($item->_a['verbose'])) {
            $name = Admin_Views_ucfirst($item->_a['verbose']);
        } else {
            $name = Admin_Views_ucfirst(str_replace('_', ' ', $item->_a['model']));
        }
        if ($request->method == 'POST') {
            $form = Pluf_Shortcuts_GetFormForModel($item, $request->POST);
            if ($form->isValid()) {
                $item = $form->save();
                Admin_Log::logAction($request->user, $item, 2);
                $request->user->setMessage(sprintf(__('The %1$s <em>%2$s</em> has been updated successfully.'), Pluf_esc($name), Pluf_esc($item)));
                $url = Pluf_HTTP_URL_urlForView('Admin_Views::listItems', array($match[1], $match[2]));
                return new Pluf_HTTP_Response_Redirect($url);

            }
        } else {
            $form = Pluf_Shortcuts_GetFormForModel($item, $item->getData());
        }
        $page_title = sprintf(__('Change %s'), $name);

        $context = array('page_title' => $page_title,
                         'user' => $request->user,
                         'item' => $item,
                         'model_name' => $name,
                         'form' => $form,
                         'app_path' => $match[1], 
                         'model_path' => $match[2]);
        return Pluf_Shortcuts_RenderToResponse('admin/edit-item.html', $context,
                                               $request);
    }

    /**
     * Delete an item of a model.
     */
    public $deleteItem_precond = array('Pluf_Precondition::staffRequired');

    function deleteItem($request, $match)
    {
        $model_name = Admin_Admin::getModelName($match[1], $match[2]);
        if (false == $model_name) {
            throw new Pluf_HTTP_Error404();
        }
        // Check the rights to edit
        if (!$request->user->hasPerm($model_name.'.delete')) {
            return new Pluf_HTTP_Response_Forbidden($request);
        }
        $item = Pluf_Shortcuts_GetObjectOr404($model_name, $match[3]);
        if (isset($item->_a['verbose'])) {
            $name = Admin_Views_ucfirst($item->_a['verbose']);
        } else {
            $name = Admin_Views_ucfirst(str_replace('_', ' ', $item->_a['model']));
        }
        if ($request->method == 'POST') {
            Admin_Log::logAction($request->user, $item, 3);
            $item->delete();
            $request->user->setMessage(sprintf(__('The %1$s <em>%2$s</em> has been deleted successfully.'), Pluf_esc($name), Pluf_esc($item)));
            $url = Pluf_HTTP_URL_urlForView('Admin_Views::listItems', array($match[1], $match[2]));
            return new Pluf_HTTP_Response_Redirect($url);
        }
        $page_title = sprintf(__('Delete %1$s %2$s'), $name, $item->__toString());
        $affected = new Pluf_Template_ContextVars($item->getDeleteSideEffect());
        $context = array('page_title' => $page_title,
                         'user' => $request->user,
                         'item' => $item,
                         'model_name' => $name,
                         'affected' => $affected,
                         'app_path' => $match[1], 
                         'model_path' => $match[2]);
        return Pluf_Shortcuts_RenderToResponse('admin/delete-item.html', $context,
                                               $request);
    }

    /**
     * Add an item.
     */
    public $addItem_precond = array('Pluf_Precondition::staffRequired');

    function addItem($request, $match)
    {
        $model_name = Admin_Admin::getModelName($match[1], $match[2]);
        if (false == $model_name) {
            throw new Pluf_HTTP_Error404();
        }
        // Check the rights to add
        if (!$request->user->hasPerm($model_name.'.create')) {
            return new Pluf_HTTP_Response_Forbidden($request);
        }
        $item = Pluf::factory($model_name);
        if (isset($item->_a['verbose'])) {
            $name = Admin_Views_ucfirst($item->_a['verbose']);
        } else {
            $name = Admin_Views_ucfirst(str_replace('_', ' ', $item->_a['model']));
        }
        if ($request->method == 'POST') {
            $form = Pluf_Shortcuts_GetFormForModel($item, $request->POST);
            if ($form->isValid()) {
                $item = $form->save();
                Admin_Log::logAction($request->user, $item, 1);
                $request->user->setMessage(sprintf(__('The %1$s <em>%2$s</em> has been created successfully.'), Pluf_esc($name), Pluf_esc($item)));
                $url = Pluf_HTTP_URL_urlForView('Admin_Views::listItems', array($match[1], $match[2]));
                return new Pluf_HTTP_Response_Redirect($url);
            }
        } else {
            $form = Pluf_Shortcuts_GetFormForModel($item);
        }
        $page_title = sprintf(__('Create %s'), $name);

        $context = array('page_title' => $page_title,
                         'user' => $request->user,
                         'item' => $item,
                         'model_name' => $name,
                         'form' => $form,
                         'app_path' => $match[1], 
                         'model_path' => $match[2]);
        return Pluf_Shortcuts_RenderToResponse('admin/add-item.html', $context,
                                               $request);
    }
}


function Admin_Views_ucfirst($str)
{
    return mb_strtoupper(mb_substr($str, 0, 1, 'UTF-8'))
        .mb_substr($str, 1, mb_strlen($str), 'UTF-8');
}